package com.jvm123.excel.in.impl;

import com.jvm123.excel.in.BeanConverter;
import com.jvm123.excel.in.FieldTypeBinder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.*;

public class BeanConverterImpl implements BeanConverter {

    private static final Logger logger = LoggerFactory.getLogger(BeanConverterImpl.class);

    private FieldTypeBinder fieldTypeBinder;

    public BeanConverterImpl() {
    }

    public BeanConverterImpl(FieldTypeBinder fieldTypeBinder) {
        if (fieldTypeBinder == null) {
            this.fieldTypeBinder = new DefaultFieldTypeBinder();
        } else {
            this.fieldTypeBinder = fieldTypeBinder;
        }
    }

    @Override
    public <T> List<T> convertToBeanList(Class<T> tClass, List<Map<String, Object>> mapList) {
        List<T> beanList = new ArrayList<>();
        for (Map<String, Object> map : mapList) {
            try {
                T entity = tClass.newInstance();
                map.forEach((k, v) -> {
                    Field field;
                    Class<?> type = null;
                    try {
                        field = tClass.getDeclaredField(k);
                        field.setAccessible(true);
                        type = field.getType();
                        Object value = fieldTypeBinder.convertFieldType(v, type);
                        field.set(entity, value);
                    } catch (NoSuchFieldException | IllegalAccessException e) {
                        logger.warn("{}对象中没有字段{}", tClass.getTypeName(), k);
                        e.printStackTrace();
                    } catch (IllegalArgumentException e1) {
                        logger.warn("数据类型不匹配：要求的类型为{}，而发现的值为{}", (type != null ? type.getName() : null), v);
                    }

                });
                beanList.add(entity);
            } catch (IllegalAccessException | InstantiationException e) {
                e.printStackTrace();
            }
        }
        logger.debug("转换为beanList：{}", beanList);
        return beanList;
    }

    public FieldTypeBinder getFieldTypeBinder() {
        return fieldTypeBinder;
    }

    public void setFieldTypeBinder(FieldTypeBinder fieldTypeBinder) {
        this.fieldTypeBinder = fieldTypeBinder;
    }
}
